項目61 Record型を使って値の同期を保つ
題材として扱う型
code:ts
interface ScatterProps {
// データ
xs: number[];
ys: number[];
// 表示
xRange: number, number;
yRange: number, number;
color: string;
// イベント
onClick?: (x: number, y: number, index: number) => void;
}
フェイルオープンとフェイルクローズドのジレンマを認識する
フェイルオープン
何らかの失敗があっても処理を継続すること
code:ts
function shouldUpdate(
oldProps: ScatterProps,
newProps: ScatterProps
) {
for (const kStr in oldProps) {
const k = kStr as keyof ScatterProps;
if (oldPropsk !== newPropsk) {
if (k !== 'onClick') return true;
}
}
return false;
}
フェイルクローズド
何らかの失敗があったときに処理を止めること
code:ts
function shouldUpdate(
oldProps: ScatterProps,
newProps: ScatterProps
) {
return (
oldProps.xs !== newProps.xs ||
oldProps.ys !== newProps.ys ||
oldProps.xRange !== newProps.xRange ||
oldProps.yRange !== newProps.yRange ||
oldProps.color !== newProps.color
// (onClickはチェックしない)
);
}
ジレンマ
フェイルオープンの選択肢を取れば、保守性は高まるが不要な継続性が生まれる
フェイルクローズドの選択肢を取れば、安全性が高まるが保守性が薄れる
ジレンマが生まれたときは、本来あるべき姿を考え直す。
今回であれば、ScatterPropsに新たなプロパティが追加されたときに型エラーを起こして実装者に問題があることを伝えれるか
上記の問題をRecord型を使って、回避する
関連する値と型を同期させる
code:ts
const REQUIRES_UPDATE: Record<keyof ScatterProps, boolean> = {
xs: true,
ys: true,
xRange: true,
yRange: true,
color: true,
onClick: false,
};
function shouldUpdate(
oldProps: ScatterProps,
newProps: ScatterProps
) {
for (const kStr in oldProps) {
const k = kStr as keyof ScatterProps;
if (oldPropsk !== newPropsk && REQUIRES_UPDATEk) {
return true;
}
}
return false;
}
型に新しいプロパティを追加すると型エラーが発生し、問題に気づくことができる
https://scrapbox.io/files/682f3675b9814426c9f7a7b2.png
#TypeScript